<?php
namespace app\common\logic;

use think\facade\Db;
use pay\wechat\WxPay;
use pay\ali\AliPay;
/**
 * 支付类
 */
class Pay
{
    public $lists=[];
    public $pk='';//主键
    public $model=[];

    /**
     * 获取html显示数据
     */
    public function getHtml($table,$ids,$user_id){
        $rs= $this->getReady($table,$ids,$user_id);
        if(!$rs['status']){
            return $rs;
        }
        $guize = $rs['result'];

        //返回显示
        $return = ['wallet'=>[],'paylist'=>[],'title'=>[],'real_total_price'=>0];

        foreach($guize as $val){
            //钱包
            if($val['wallet']){
                $wallet = array_keys($val['wallet']);
                $return['wallet'] = array_merge($wallet,$return['wallet']);
            }
            //只获取一次
            if($val['onlinepay'] && count($return['paylist'])==0){
                //获取在线支付
                $onlinepay = logic('Wallet')->getOnlinePay();
                $pay = $onlinepay['result']['pay'];
                $return['paylist']=$pay;
            }

            //支付金额和支付标题//抵扣的先不在页面展示
            //if(!$val['dikou']){
                !isset($return['title'][$val['name']]) && $return['title'][$val['name']]=0;
                $real_total_price = $this->getSum($val['ziduan']);
                $return['title'][$val['name']] += $real_total_price;
            $return['real_total_price'] += $real_total_price;
            //}
        }

        //钱包余额
        if(count($return['wallet'])){
            $walletname = logic('Wallet')->getName();
            //获取钱包
            $userwallet = Db::name('wallet')->where('user_id',$user_id)->find();
            foreach($return['wallet'] as $wv){
                $return['qianbao'][$walletname[$wv]]=$userwallet[$wv];
            }
            unset($return['wallet']);
        }

        return ['status'=>1,'result'=>$return];
    }

    /**
     * 获取总和
     */
    public function getSum($str){
        $lists = $this->lists;
        $num = 0;
        foreach($lists as $list){
            $num+=$this->jiexi($str,$list);
        }
        return $num;
    }

    /**
     * 获取支付规则
     */
    public function getReady($table,$ids,$user_id)
    {
        $model = model($table);
        $this->model=$model;
        //支付前--可以变动价格或者其他
        if(method_exists($model,'beforePay')){
            $model->beforePay($ids);
        }
        //主键
        $pk = $model->getPk();
        $this->pk = $pk;
        //判断状态
        $map = [
            $pk=>['in',$ids],
            'user_id'=>$user_id,
        ];
        if($table=='order'){
            $username = Db::name('users')->where(['user_id'=>$user_id])->value('username');
            $map[] = ['exp',"user_id = ".$user_id." or df_username = '".$username."'"];
            $map = [
                $pk=>['in',$ids],
            ];
        }else{
            $map = [
                $pk=>['in',$ids],
            ];
        }
        //一般只有多购物车情况下，会出现多个订单一起支付
        $lists = $model->where($map)->select()->toArray();
        if(!$lists){
            return ['status'=>0,'msg'=>'支付信息获取失败'];
        }
        foreach($lists as $k=>$list){
            if($list['order_status']!=0){
                return ['status'=>0,'msg'=>'支付状态有误'];
            }
            //if(!empty($list['total_fluse_pay']) && $list['total_fluse_pay']>0){
                //减掉已支付的抵扣部分
            if($table=='order'){
                $lists[$k]['total_shop_price'] =  bcsub($list['total_shop_price'],$list['total_youhui_pay'],2);
            }

            //}
        }

       // dump($lists);exit;
        $this->lists= $lists;

        //获取规则
        //先抵扣，先排序
        $rules = Db::name('payrule')->where(['biaoming'=>$table])->order('dikou desc,px desc')->select();
        if(!$rules){
            return ['status'=>0,'msg'=>'未找到对应的支付规则'];
        }

        //选出可用的规则
        $guize = [];
        foreach($lists as $list){
            foreach($rules as $rule){
                //不使用福利积分
                if($table=='order' && ($list['nousefl']==1 || $list['df_username']==$username) && $rule['id']==16){
                    continue;
                }
                $yes = $this->jiexi($rule['tiaojian'],$list);
                if($yes){
                    if($rule['wallet']) {
                        $rule['wallet'] = unserialize($rule['wallet']);
                        //排序--最小的在前
                        asort($rule['wallet']);
                    }
                    $guize[] = $rule;
                }
            }
            break;
        }

        if(!count($guize)){
            return ['status'=>0,'msg'=>'未找到匹配的支付规则'];
        }

        return ['status'=>1,'result'=>$guize];
    }

    /**
     * 解析表达式
     */
    function jiexi($str,$info){
        $fields = logic('Preg')->bracket($str);
        if($fields){
            //替换数值
            foreach($fields as $key=>$val){
                $num = $info[$val[1]]?:0;
                $str = str_replace($val[0],$num,$str);
            }

        }
        $str = str_replace('=','==',$str);
        $result=eval("return $str;");
        return $result;
    }

    /**
     * 支付,组织数据
     */
    public function pay($table,$ids,$user_id){
        //获取支付规则
        $rs = $this->getReady($table,$ids,$user_id);
        if(!$rs['status']){
            return $rs;
        }else{
            $rules = $rs['result'];
            //钱包名称
            $walletanme = logic('Wallet')->getName();
            //获取钱包
            $userwallet = Db::name('wallet')->where('user_id',$user_id)->find();
            //循环订单
            $lists = $this->lists;

            $payids = '';
            $payment=[];//支付金额数组
            $payprice = 0;//在线支付金额
            foreach($lists as $list){
                $dikou=[];//抵扣数组
                $paywallet = [
                    'onlinepay' => 0
                ];//本次订单使用钱包
                //循环规则
                foreach($rules as $rule){

                    //待支付金额
                    $price = $this->jiexi($rule['ziduan'],$list);
                    //减去抵扣的金额
                    if(isset($dikou[$rule['id']])){
                        $price -=$dikou[$rule['id']];
                    }
                    if($price>0){
                        //循环钱包
                        if($rule['wallet']!='' && count($rule['wallet'])>=1) {
                            $shengyu = $price;//剩余

                            $total_shiyong = 0;//本次规则总使用
                            //依次扣除钱包
                            foreach($rule['wallet'] as  $wk=>$wv){
                                //判断钱包
                                if($userwallet[$wk]>=$shengyu){//钱包多，使用剩余支付金额
                                    $shiyong = $shengyu;
                                }elseif($wk=='youhui'){
                                    return ['status'=>0,'msg'=>'优惠券钱包余额不足'];
                                }else{//钱包少，使用余额
                                    $shiyong = $userwallet[$wk];
                                }
                                $userwallet[$wk]-=$shiyong;//钱包减少
                                $shengyu -=$shiyong;//还剩多少

                                $total_shiyong+=$shiyong;//总使用

                                //实际钱包使用累加
                                !isset($paywallet[$wk]) && $paywallet[$wk]=0;
                                $paywallet[$wk]+=number_format($shiyong,'2','.','');
                            }
                            //抵扣，有可能多个抵扣规则
                            if($total_shiyong>0 && $rule['dikou']){
                                !isset($dikou[$rule['dikou_id']]) && $dikou[$rule['dikou_id']]=0;
                                $dikou[$rule['dikou_id']]+=$total_shiyong;
                            }
//dump($shiyong);dump($shengyu);
                            //还有剩余
                            if($shengyu>0){
                                //不是抵扣也没开启在线支付,提示最后一个钱包余额不足
                                if(!$rule['dikou']){
                                    if(!$rule['onlinepay']){
                                        return ['status'=>0,'msg'=>$walletanme[$wk].'不足'];
                                    }else{
                                        $payprice+=$shengyu;//在线支付金额增加
                                        $paywallet['onlinepay'] +=$shengyu;
                                    }
                                }
                            }
                        }else{
                            $payprice+=$price;//在线支付金额增加
                            $paywallet['onlinepay'] +=$price;
                        }
                    }
                }//dump($paywallet);dump($dikou);
                if($paywallet){
                    $payment[$list[$this->pk]] = $paywallet;
                }

                //此处用于在线支付
                $payids.= ",".$list[$this->pk];
            }

            //转换价格
            foreach($payment as $k=>$v){
                foreach($v as $k1=>$v1){
                    $payment[$k][$k1] = number_format($payment[$k][$k1],'2','.','');
                }
            }
            //dump($payprice);dump($payment);exit();
            //在线支付
            if($payprice>0){

                //插入在线支付表
                $payline = [];
                $payline['order_no'] = date('YmdHis').rand(100000,999999).str_replace(',','',$payids);
                $payline['paytype'] = input('typeid');//在线支付方式
                //记录钱包消费分配
                if($payment){
                    $payline['payment'] = serialize($payment);
                }//dump($payline);exit;

                $payline['ids'] = trim($payids,',');//记录哪几个订单需要支付
                $payline['table'] = $table;//哪个表
                $payline['w_time'] = time();
                $payline['pay_price'] = $payprice;
                $payline['user_id'] = $user_id;
                $payline['payname'] = $rule['action'];
                $rs = Db::name('payment')->insertGetId($payline);
                if(!$rs){
                    return ['status'=>0,'msg'=>'添加在线支付订单失败'];
                }
                return ['status'=>2,'id'=>$rs,'money'=>$payprice];

            }else{
                if(count($payment)){
                    $payname=$rule['action'];

                    //扣款
                    $pay_time = getCurTime();
                    foreach($payment as $id=>$pay){
                        $savea = ['order_status'=>1,'pay_time'=>$pay_time,'payment'=>serialize($pay)];
                        //更新状态
                        if($table=='order'){
                            $ordera = Db::name($table)->where($this->pk,$id)->find();
                            //如果是本人支付，删除代付人
                            if($ordera['user_id']==$user_id && $ordera['df_username']!=''){
                                $savea['df_username'] = '';
                            }
                        }
                        $rs = Db::name($table)->where($this->pk,$id)->save($savea);
                        if(!$rs){
                            return ['status'=>0,'msg'=>'更新支付状态失败'];
                        }
                        foreach($pay as $wk=>$money){
                            if($money>0){
                                $rs = qianbao($user_id,-$money,$wk,$payname,'支付单号'.$id);
                                if(!$rs['status']){
                                    return $rs;
                                }
                            }

                        }
                        //支付后
                        if(method_exists($this->model,'afterPay')){
                           $rs = $this->model->afterPay($id);
                           if(!$rs['status']){
                               return $rs;
                           }
                        }
                    }
                    return ['status'=>1,'msg'=>'支付成功'];
                }else{
                    return ['status'=>0,'msg'=>'支付余额有误'];
                }
            }
        }
    }

    //微信小程序支付
    public function wxapp_pay($payment_id,$platform){
        $url = getCurUrl();
        $rsorder = Db::name("payment")->where(array('id'=>$payment_id,'status'=>0))->find();
        $openid = Db::name('social')->where('user_id',$rsorder['user_id'])->value('wxapp_openid');
        if(!$openid){
//            $result = [
//                'status' => false,
//                'msg' => '请求失败，未绑定微信',
//                'data' => []
//            ];
//            return $result;
        }
        $redirect_url = tpCache('weixin.redirect_url');
        $rsorder['pay_price'] = intval(bcmul($rsorder['pay_price'],100));
        //$response = logic('WxappPay')->getPrePayOrder2('购买产品', $rsorder['order_no'], $rsorder['pay_price'], $url.'Mobile/Payment/noticeys',$openid);

        $paysdk = new WxPay();
//        $response = $paysdk->app_pay($rsorder);
//        dump($response);exit;
        if($platform=='h5'){
            //支付宝h5支付
            $response = $paysdk->h5_pay($rsorder);
        }else if($platform=='app'){
            //支付宝app支付
            $response = $paysdk->app_pay($rsorder);
        }else{
            //支付宝小程序支付
            $response = $paysdk->native_pay($rsorder);
        }

        if ($response['status'] ){
            $result = [
                'status' => true,
                'msg' => '请求成功！',
                'data' =>$response['data']
            ];
            return $result;
        }else{
            $result = [
                'status' => false,
                'msg' => '请求失败，'.$response['msg'],
                'data' => []
            ];
            return $result;
        }
    }
    //支付宝wap支付
    public function ali_pay($payment_id,$platform){
        $url = getCurUrl();
        $rsorder = Db::name("payment")->where(array('id'=>$payment_id,'status'=>0))->field('payname,order_no,user_id,pay_price')->find();

        $rsorder['pay_price'] = number_format($rsorder['pay_price'],2,'.','');
        //$response = logic('WxappPay')->getPrePayOrder2('购买产品', $rsorder['order_no'], $rsorder['pay_price'], $url.'Mobile/Payment/noticeys',$openid);

        $paysdk = new Alipay();
        if($platform=='h5'){
            //支付宝h5支付
            $response = $paysdk->wapay($rsorder);
        }else if($platform=='app'){
            //支付宝app支付
            $response = $paysdk->apppay($rsorder);
        }else{
            //支付宝小程序支付
            $response = $paysdk->ali_pay($rsorder);
        }
        return $response;
        if(!empty($response->body)){
            return ['status'=>1,'data'=>$response->body];
        }else{
            return ['status'=>0,'msg'=>'支付失败'];
        }
    }

}